{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Provides a Summary of Garmin Daily Monitoring Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import display, Markdown\n",
    "import snakemd\n",
    "\n",
    "import fitfile\n",
    "from garmindb import GarminConnectConfigManager\n",
    "from garmindb.garmindb import GarminDb, Attributes, Weight, Stress, RestingHeartRate, IntensityHR, Sleep\n",
    "from garmindb.garmindb import MonitoringDb, Monitoring, MonitoringHeartRate, MonitoringIntensity, MonitoringClimb\n",
    "\n",
    "from jupyter_funcs import format_number\n",
    "\n",
    "\n",
    "gc_config = GarminConnectConfigManager()\n",
    "db_params_dict = gc_config.get_db_params()\n",
    "garmin_db = GarminDb(db_params_dict)\n",
    "garmin_mon_db = MonitoringDb(db_params_dict)\n",
    "\n",
    "measurement_system = Attributes.measurements_type(garmin_db)\n",
    "unit_strings = fitfile.units.unit_strings[measurement_system]\n",
    "distance_units = unit_strings[fitfile.units.UnitTypes.distance_long]\n",
    "\n",
    "doc = snakemd.new_doc()\n",
    "\n",
    "doc.add_heading(\"Monitoring Statistics\")\n",
    "doc.add_paragraph(\"Analysis of all monitoring data in the database.\")\n",
    "\n",
    "def __get_col_stats(table, col, name, ignore_le_zero=False, time_col=False):\n",
    "    records = table.row_count(garmin_db)\n",
    "    if time_col:\n",
    "        maximum = table.get_time_col_max(garmin_db, col)\n",
    "    else:\n",
    "        maximum = format_number(table.get_col_max(garmin_db, col))\n",
    "    if time_col:\n",
    "        minimum = table.get_time_col_min(garmin_db, col)\n",
    "    else:\n",
    "        minimum = format_number(table.get_col_min(garmin_db, col, None, None, ignore_le_zero))\n",
    "    if time_col:\n",
    "        average = table.get_time_col_avg(garmin_db, col)\n",
    "    else:\n",
    "        average = format_number(table.get_col_avg(garmin_db, col, None, None, ignore_le_zero))\n",
    "    if time_col:\n",
    "        latest = table.get_col_latest(garmin_db, col)\n",
    "    else:\n",
    "        latest = format_number(table.get_col_latest(garmin_db, col))\n",
    "    return [name, records, maximum, minimum, average, latest]\n",
    "\n",
    "doc.add_table(\n",
    "    ['Name', 'Records', 'Maximum', 'Minimum', 'Average', 'Latest'],\n",
    "    [\n",
    "        __get_col_stats(Weight, Weight.weight, 'Weight'),\n",
    "        __get_col_stats(Stress, Stress.stress, 'Stress', True),\n",
    "        __get_col_stats(RestingHeartRate, RestingHeartRate.resting_heart_rate, 'RHR', True),\n",
    "        __get_col_stats(Sleep, Sleep.total_sleep, 'Sleep', True, True),\n",
    "        __get_col_stats(Sleep, Sleep.rem_sleep, 'REM Sleep', True, True)\n",
    "    ])\n",
    "\n",
    "def __get_monitoring_days(year):\n",
    "    days = Monitoring.get_days(garmin_mon_db, year)\n",
    "    days_count = len(days)\n",
    "    if days_count > 0:\n",
    "        first_day = days[0]\n",
    "        last_day = days[-1]\n",
    "        span = last_day - first_day + 1\n",
    "    else:\n",
    "        span = 0\n",
    "    doc.add_paragraph(f\"{year} Days with data ({days_count} count vs {span} span): {days}\")\n",
    "    for index in range(days_count - 1):\n",
    "        day = int(days[index])\n",
    "        next_day = int(days[index + 1])\n",
    "        if next_day != day + 1:\n",
    "            day_str = str(fitfile.conversions.day_of_the_year_to_datetime(year, day))\n",
    "            next_day_str = str(fitfile.conversions.day_of_the_year_to_datetime(year, next_day))\n",
    "            doc.add_paragraph(f\"Days gap between {day} ({day_str}) and {next_day} ({next_day_str})\")\n",
    "    return days_count\n",
    "\n",
    "def __get_monitoring_months(year):\n",
    "    months = Monitoring.get_month_names(garmin_mon_db, year)\n",
    "    doc.add_paragraph(f\"{year} Months with data ({len(months)}): {months}\")\n",
    "\n",
    "doc.add_heading(\"Monitoring Records Coverage\", 3)\n",
    "doc.add_paragraph(\"This shows periods that data has been downloaded for. \"\n",
    "                    \"Not seeing data for days you know Garmin has data? \"\n",
    "                    \"Change the starting day and the number of days in GarminConnectConfig.json and do a full download.\")\n",
    "years = Monitoring.get_years(garmin_mon_db)\n",
    "doc.add_paragraph(f\"Monitoring records: {Monitoring.row_count(garmin_mon_db)}\")\n",
    "doc.add_paragraph(f\"Monitoring Years with data ({len(years)}): {years}\")\n",
    "total_days = 0\n",
    "for year in years:\n",
    "    doc.add_heading(str(year), 4)\n",
    "    __get_monitoring_months(year)\n",
    "    total_days += __get_monitoring_days(year)\n",
    "doc.add_paragraph(f\"Total days with monitoring data: {total_days}\")\n",
    "\n",
    "display(Markdown(str(doc)))"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "bfd9857ee3bb42c16b52c1ffe04453343fea53c05fc5f9f2d5ac6a881cdaa36c"
  },
  "kernelspec": {
   "display_name": "Python 3.9.10 ('.venv': venv)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
